package gu.simplemq;

import java.net.URI;
import java.net.URISyntaxException;

import static com.google.common.base.MoreObjects.firstNonNull;
import static com.google.common.base.Preconditions.checkNotNull;

import com.google.common.base.Strings;
import com.google.common.net.HostAndPort;

public abstract class BaseMQURI{
	private final URI uri;
	private final MQConstProvider constProvider = getConstProvider();
	
	protected BaseMQURI(String uri)  {
		this(URI.create(checkNotNull(Strings.emptyToNull(uri),"uri is null or emtpy")));
	}
	protected BaseMQURI(URI uri) {
		this.uri = normalized(uri);
	}
	protected BaseMQURI(String host, Integer port) {
		try {
			uri = new URI(constProvider.getProtocol(),
					null,
					firstNonNull(host, constProvider.getDefaultHost()),
					firstNonNull(port, constProvider.getDefaultPort()),
					null,
					null,
					null);
		} catch (URISyntaxException e) {
			throw new RuntimeException(e);
		}
	}
	protected BaseMQURI(HostAndPort hostAndPort) {
		this(hostAndPort.getHost(),hostAndPort.getPort());
	}
	protected abstract MQConstProvider getConstProvider();
	
	public URI getUri() {
		return uri;
	}
	public URI asLocation() {
		try {
			return new URI(uri.getScheme(), 
					null, 
					uri.getHost(),
					uri.getPort(), 
					uri.getPath(), 
					null, 
					null);
		} catch (URISyntaxException e) {
			throw new RuntimeException(e);
		}
	}

	public String getHost(){
		return uri.getHost();
	}
	public int getPort(){
		return uri.getPort();
	}
	public String getUsername(){
		return getUsername(uri);
	}
	public String getPassword(){
		return getPassword(uri);
	}

	public static String getPassword(URI uri) {
		String userInfo = uri.getUserInfo();
		if (userInfo != null) {
			return userInfo.split(":", 2)[1];
		}
		return null;
	}
	public static String getUsername(URI uri) {
		String userInfo = uri.getUserInfo();
		if (userInfo != null) {
			return userInfo.split(":", 2)[0];
		}
		return null;
	}
	private String convertHost(String host) {
		if ("127.0.0.1".equals(host)) {
			return constProvider.getDefaultHost();
		}
		else if ("::1".equals(host)) {
			return constProvider.getDefaultHost();
		}
		
		return host;
	}
	/**
	 * 返回归一化的{@link URI}对象，such as jedis://192.168.1.100:6379/0<br>
	 * 如果没有指定scheme,则使用默认值{@link #getProtocol()},
	 * 如果没有指定host,则使用默认值{@link #getDefaultHost()},
	 * 如果没有指定port,则使用默认值{@link #getDefaultPort()},
	 * @param uri 为{@code null}返回 'tcp://localhost:61616'
	 */
	private URI normalized(URI uri){
		try {
			if(null == uri){
				return URI.create(constProvider.getDefaultMQLocation());
			}
			return new URI(firstNonNull(uri.getScheme(),constProvider.getProtocol()), 
					uri.getUserInfo(), 
					firstNonNull(convertHost(uri.getHost()),constProvider.getDefaultHost()),
					uri.getPort() == -1 ? constProvider.getDefaultPort() : uri.getPort(), 
					uri.getPath(), 
					uri.getQuery(), 
					uri.getFragment());
		} catch (URISyntaxException e) {
			throw new RuntimeException(e);
		}
	}
	@Override
	public String toString() {
		return uri.toString();
	}
}
